package au.com.iglootech.component;

import java.util.Collection;

import org.apache.commons.lang3.StringUtils;

import com.vaadin.data.Property;
import com.vaadin.data.Validator;
import com.vaadin.data.Validator.InvalidValueException;
import com.vaadin.data.validator.IntegerValidator;
import com.vaadin.terminal.PaintException;
import com.vaadin.terminal.PaintTarget;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.Field;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.TextField;

public class IGTTfnField extends CustomComponent implements Field {

	private HorizontalLayout mainLayout = new HorizontalLayout();

	private TextField firstField;
	private TextField secondField;
	private TextField thirdField;

	private boolean bInvalidCommitted;
	private boolean bWriteThrough;
	private boolean bReadThrough;

	private boolean isRequired;
	private String requiredMessage;

	public IGTTfnField() {
		super();
		initContent();
		setCompositionRoot(mainLayout);
	}

	protected void initContent() {
		firstField = new TfnUnitField();
		secondField = new TfnUnitField();
		thirdField = new TfnUnitField();
		mainLayout.setSpacing(true);
		mainLayout.addComponent(firstField);
		mainLayout.addComponent(new Label(" - "));
		mainLayout.addComponent(secondField);
		mainLayout.addComponent(new Label(" - "));
		mainLayout.addComponent(thirdField);

	}

	@Override
	public boolean isInvalidCommitted() {
		// TODO Auto-generated method stub
		return bInvalidCommitted;
	}

	@Override
	public void setInvalidCommitted(boolean isCommitted) {
		bInvalidCommitted = isCommitted;
	}

	@Override
	public void commit() throws SourceException, InvalidValueException {
		if (StringUtils.isEmpty((String) firstField.getValue())
				|| StringUtils.isEmpty((String) secondField.getValue())
				|| StringUtils.isEmpty((String) thirdField.getValue())) {
			throw new InvalidValueException("Invalid TFN");
		}

	}

	@Override
	public void discard() throws SourceException {
		// TODO Auto-generated method stub

	}

	@Override
	public boolean isWriteThrough() {
		return bWriteThrough;
	}

	@Override
	public void setWriteThrough(boolean writeThrough) throws SourceException,
			InvalidValueException {
		bWriteThrough = writeThrough;
	}

	@Override
	public boolean isReadThrough() {
		return bReadThrough;
	}

	@Override
	public void setReadThrough(boolean readThrough) throws SourceException {
		bReadThrough = readThrough;
	}

	@Override
	public boolean isModified() {
		return false;
	}

	@Override
	public void addValidator(Validator validator) {
		// TODO Auto-generated method stub

	}

	@Override
	public void removeValidator(Validator validator) {
		// TODO Auto-generated method stub

	}

	@Override
	public Collection<Validator> getValidators() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public boolean isValid() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void validate() throws InvalidValueException {
		// TODO Auto-generated method stub

	}

	@Override
	public boolean isInvalidAllowed() {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public void setInvalidAllowed(boolean invalidValueAllowed)
			throws UnsupportedOperationException {
		// TODO Auto-generated method stub

	}

	@Override
	public Object getValue() {
		// TODO Auto-generated method stub
		return (String) firstField.getValue() + (String) secondField.getValue()
				+ (String) thirdField.getValue();
	}

	@Override
	public void setValue(Object newValue) throws ReadOnlyException,
			ConversionException {
		if (!(newValue instanceof String)) {
			throw new ConversionException();
		}
		String tfn = (String) newValue;
		if (tfn.length() != 9) {
			throw new ConversionException("TFN must have 9 bit charactors");
		}
		firstField.setValue(tfn.substring(0, 2));
		secondField.setValue(tfn.substring(3, 5));
		thirdField.setValue(tfn.substring(6, 8));
	}

	@Override
	public Class<?> getType() {
		// TODO Auto-generated method stub
		return IGTTfnField.class;
	}

	@Override
	public void addListener(ValueChangeListener listener) {
		// TODO Auto-generated method stub

	}

	@Override
	public void removeListener(ValueChangeListener listener) {
		// TODO Auto-generated method stub

	}

	@Override
	public void valueChange(com.vaadin.data.Property.ValueChangeEvent event) {
		// TODO Auto-generated method stub

	}

	@Override
	public void setPropertyDataSource(Property newDataSource) {
		// TODO Auto-generated method stub

	}

	@Override
	public Property getPropertyDataSource() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public int getTabIndex() {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public void setTabIndex(int tabIndex) {
		// TODO Auto-generated method stub

	}

	@Override
	public boolean isRequired() {
		return isRequired;
	}

	@Override
	public void setRequired(boolean required) {
		isRequired = required;
		requestRepaint();
	}

	@Override
	public void setRequiredError(String requiredMessage) {
		this.requiredMessage = requiredMessage;
		requestRepaint();
	}

	@Override
	public String getRequiredError() {
		return requiredMessage;
	}

	public void focus() {
		super.focus();
	}

	@Override
	public void paintContent(PaintTarget target) throws PaintException {

		// The tab ordering number
		if (getTabIndex() != 0) {
			target.addAttribute("tabindex", getTabIndex());
		}

		// If the field is modified, but not committed, set modified attribute
		if (isModified()) {
			target.addAttribute("modified", true);
		}

		// Adds the required attribute
		if (!isReadOnly() && isRequired()) {
			target.addAttribute("required", true);
		}
		super.paintContent(target);
	}

	public class TfnUnitField extends TextField {
		public TfnUnitField() {
			setMaxLength(3);
			setWidth("30px");
			addValidator(new IntegerValidator("TFN must be an Integer"));
		}
	}
}
